package com.dsteiner.gwt.cafeteriasophia.client.domain;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.persistence.OneToMany;

import com.dsteiner.widgets.client.domain.ModelObject;
import com.dsteiner.widgets.client.domain.Searchable;
import com.dsteiner.widgets.client.domain.SearchableId;
import com.dsteiner.widgets.client.domain.SearchableProperty;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Searchable
public class ShiftChange extends ModelObject{

	@PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    @SearchableId
    private String id;
	
	@Persistent(defaultFetchGroup="true")
    private List<Stock> stocks = new ArrayList<Stock>();
	
	@Persistent(defaultFetchGroup="true")
	private List<Sale> sales = new ArrayList<Sale>();
	
	@Persistent(defaultFetchGroup="true")
	private List<Purchase> purchases = new ArrayList<Purchase>();
	
    @Persistent
    @SearchableProperty
	private Date date = new Date();
    
    @Persistent
    @SearchableProperty
    private String employee;
    
    @Persistent
    private Date registeredDate = new Date();
    
    @Persistent
    private Date editDate;
 
	public ShiftChange() {
	}

	@Override
	public String getId() {
		return id;
	}
	@Override
	public void setId(String id) {
		this.id = id;
	}

	@Override
	public Date getRegisteredDate() {
		return registeredDate;
	}
	public void setRegisteredDate(Date registeredDate) {
		this.registeredDate = registeredDate;
	}

	public void setEmployee(String employee) {
		this.employee = employee;
	}
	public String getEmployee() {
		return employee;
	}

	public void setEditDate(Date editDate) {
		this.editDate = editDate;
	}
	public Date getEditDate() {
		return editDate;
	}
	
	public List<Sale> getSales(Product product){
		return hasProduct(product, sales);
	}

	private <T extends HasProduct> List<T> hasProduct(Product product, List<T> products) {
		List<T> hasProducts = new ArrayList<T>();
		for (T hasProduct : products) {
			if(product.equals(hasProduct.getProduct()))
				hasProducts.add(hasProduct);
		}
		return hasProducts;
	}
	public List<Purchase> getPurchases(Product product){
		return hasProduct(product, purchases);
	}
	public Stock getStock(Product product){
		List<Stock> stocks = hasProduct(product, this.stocks);
		return stocks != null && !stocks.isEmpty() ? stocks.get(0) : null;
	}
	
	public double getSalesSum(Product product){
		List<Sale> salesProduct = getSales(product);
		double value = 0;
		if(salesProduct == null)
			return value;
		for (Sale sale : salesProduct) {
			value += sale.getAmount();
		}
		return value;
	}
	public double getPurchasesSum(Product product){
		List<Purchase> purchasesProduct = getPurchases(product);
		double value = 0;
		if(purchasesProduct == null)
			return value;
		for (Purchase purchase : purchasesProduct) {
			value += purchase.getAmount();
		}
		return value;
	}
	public double getSalesValue(Product product){
		List<Sale> salesProduct = getSales(product);
		double value = 0;
		if(salesProduct == null)
			return value;
		for (Sale sale : salesProduct) {
			value += sale.value();
		}
		return value;
	}
	public double getEarnings(Product product){
		List<Sale> salesProduct = getSales(product);
		double earnings = 0;
		if(salesProduct == null)
			return earnings;
		double cost = product.getCost() != null ? product.getCost() : 0;
		for (Sale sale : salesProduct) {
			if(sale.getAmount() > 0)
				earnings += sale.value() - (sale.getAmount() * cost);
		}
		return earnings;
	}
	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
	public void setPurchases(List<Purchase> purchases) {
		this.purchases = purchases;
	}
	public void setSales(List<Sale> sales) {
		this.sales = sales;
	}
	public void setStocks(List<Stock> stocks) {
		this.stocks = stocks;
	}
	public List<Stock> getStocks() {
		return stocks;
	}
	public List<Purchase> getPurchases() {
		return purchases;
	}
	public List<Sale> getSales() {
		return sales;
	}
	@Override
	public String toString() {
		return "Cambio de turno:"+date+"|employee:"+employee+"|stocks:"+stocks+"|sales:"+sales+"|purchases:"+purchases;
	}

	public double getStockSum(Product product) {
		List<Stock> stocksProduct = hasProduct(product, stocks);
		double amount = 0;
		if(stocksProduct == null)
			return amount;
		for (Stock stock : stocksProduct) {
			amount += stock.getAmount();
		}
		return amount;
	}
}
